from mcpy.decorators import reflectable, method, constructor
from dataclasses import field
from .module import DevicesModule, sensor_status


class SensorInfo:
    name: str
    value: float
    status: sensor_status

    @constructor(noexcept=True)
    def __init__(self) -> None:
        self.name = "default_sensor"
        self.value = 0.0
        self.status = sensor_status.INACTIVE


@reflectable("Sensor", module=DevicesModule)
class Sensor:
    _info: SensorInfo

    @constructor(noexcept=True)
    def __init__(self) -> None:
        self._info: SensorInfo = SensorInfo()

    @method(name="SetName")
    def set_name(self, name: str) -> None:
        self._info.name = name

    @method(name="GetName")
    def get_name(self) -> str:
        return self._info.name

    @method(name="Initialize")
    def initialize(self) -> bool:
        return True

    @method(name="Read")
    def read(self) -> float:
        self._info.value = 25.0
        return self._info.value

    @method(name="GetValue")
    def get_value(self) -> float:
        return self._info.value

    @method(name="GetStatus")
    def get_status(self) -> sensor_status:
        return self._info.status

    @method(name="SelfTest")
    def self_test(self) -> bool:
        return True


@reflectable("DeviceManager", module=DevicesModule)
class DeviceManager:
    _sensors: list[Sensor]
    _count: int = field(default=0, name="Count")

    @method(name="CreateSensor")
    def create_sensor(self, name: str) -> None:
        s = Sensor()
        s.set_name(name)
        s.initialize()
        self._sensors.append(s)

    @method(name="SensorCount")
    def sensor_count(self) -> int:
        return len(self._sensors)

    @method(name="ReadAllSensors")
    def read_all_sensors(self) -> None:
        for s in self._sensors:
            s.read()

    @method(name="GetAverageValue")
    def get_average_value(self) -> float:
        if not self._sensors:
            return 0.0
        v = [s.get_value() for s in self._sensors]
        a = sum(v) / len(self._sensors)
        b = sum(s.get_value() for s in self._sensors)
        return a + b

    @method(name="ListSensors")
    def list_sensors(self) -> list[str]:
        return [s.get_name() for s in self._sensors]
